#include "protocol.h"


QString get_7E_remote_cmd_analysis(uint8 cmd)
{
    QString filter_tmp = model_7E_RemoteCMD->filter();
    model_7E_RemoteCMD->setFilter(QString("cmd LIKE '%%1%' ").arg(cmd,2,16,(QChar)'0') );

    QString ret_str;
    ret_str += QString("0x%1 ").arg(cmd,2,16,(QChar)'0');
    if(model_7E_RemoteCMD->rowCount()<1)//未找到
    {
        ret_str += QString("无法解析该CMD");
    }
    else
    {
        ret_str += model_7E_RemoteCMD->record(0).value("instruction").toString();//只筛选出一条信息的话，筛选结果位于record(0)中
    }

    model_7E_RemoteCMD->setFilter(filter_tmp);
    return ret_str;
}



/***************************************************************
函数名：get_smart_frame
描  述：判断是否接受到完整的一帧数据（7E协议）
       举例：7e 7e 00 00 00 01 00 00 00 02 72 04 02 02 02 02 cs
输入值：rxframe_raw[] 数据指针 rxlen 数据长度
输出值：无
返回值：SHS_frame *pframe （NULL 无）
***************************************************************/
struct SHS_frame *get_smart_frame(uint8 rxframe_raw[],uint8 rxlen)
{
    struct SHS_frame *pframe;
    uint8 i=0;
    uint8 len;

start_lbl:
    while(i < rxlen)
    {
        if(STC == rxframe_raw[i]) break;
        i++;
    }
    if(rxlen-i < SHS_FRAME_HEAD) return(NULL);//接收等待length长度
    pframe = (struct SHS_frame*)&rxframe_raw[i];
    len = pframe->length;

    if(i+SHS_FRAME_HEAD+len+1 > rxlen)
    {
        i++;
        goto start_lbl;
    }

    if(pframe->infor[len] != checksum((uint8 *)pframe, len+SHS_FRAME_HEAD))
    {
        i++;
        goto start_lbl;
    }

    return(pframe);
}
/*
功能：根据7E的DID，解析出DID对应的文字说明
参数：DID字符串，如"C012"，解析结果输出在字符串AnalyStr中,解析方式输出在analysisType
*/
void get_7E_did_analysis(QString did_str, QString &DidAnalyStr, QString &analysisType)
{
    QString filter_tmp = model_7E_did->filter();
    model_7E_did->setFilter("");
    int row=0;
    for(row=0;row<model_7E_did->rowCount();row++ )
    {
        QString dbDId_str = model_7E_did->record(row).value("did").toString();
        if(dbDId_str == did_str)
        {
            break;
        }
    }
    if(row >= model_7E_did->rowCount())
    {
        DidAnalyStr += "无法解析该did";
    }
    else
    {
        DidAnalyStr += model_7E_did->record(row).value("instruction").toString();//只筛选出一条信息的话，筛选结果位于record(0)中
        analysisType = model_7E_did->record(row).value("analysisType").toString();
    }

    model_7E_did->setFilter(filter_tmp);

//    model_7E_did->setFilter(QString("did LIKE '%%1%' ").arg(did_str));
//    model_7E_did->select();
//    if(model_7E_did->rowCount()<1)//未找到
//    {
//        DidAnalyStr = "无法解析该did";
//    }
//    else
//    {
//        DidAnalyStr = model_7E_did->record(0).value("instruction").toString();//只筛选出一条信息的话，筛选结果位于record(0)中
//        analysisType = model_7E_did->record(0).value("analysisType").toString();
//    }

//     model_7E_did->setFilter("");
}
/*
功能：解析body区域（body=did_ctrl+data）
参数：报文的FBD->body首地址body，接收解析文字的引用BodyAnalyStr
*/
void get_7E_body_analysis(struct FBD_body *body, QString &AnalyStr)
{
    qDebug()<<"did arr->";
    print_arr(body,2);
    QString  did_str = QString("%1").arg(get_le_val(body,2),4,16,(QChar)'0').toUpper();
    qDebug()<<"did_str->"<<did_str;


    AnalyStr += "<p>DID:<gy>0x"+ did_str +", 功能是:";
    QString did_analy_str;
    QString analysisType="";
    get_7E_did_analysis(did_str,did_analy_str,analysisType);//获取did的解析
    AnalyStr += did_analy_str + "</gy></p>";

    AnalyStr += "<p>Ctrl:<gy>0x"+ QString("%1 (dec=%2)")
            .arg(body->ctrl,2,16,(QChar)'0').toUpper()
            .arg(body->ctrl,3,10)
            +"</gy></p>";
    int data_len = body->ctrl & 0x7f;

    if(data_len == 0)
        return;

    AnalyStr += "<p>data:<gy>";
    for(uint8 i=0;i<data_len;i++)
    {
        AnalyStr += QString("%1").arg((quint8)body->data[i],2,16,(QChar)'0').toUpper() +" ";
    }


    if(body->ctrl & 0x80)//数据域有误
    {
        AnalyStr += "<p>数据域解析：<gy>";
        quint16 err_code=(body->data[1]<<8) + body->data[0];
        switch(err_code)
        {
            case 0x0001:  AnalyStr += "数据域长度错误";break;
            case 0x0002:  AnalyStr += "缓冲区满错误";break;
            case 0x0003:  AnalyStr += "数据域格式错误";break;
            case 0x0004:  AnalyStr += "数据项不存在";break;
            case 0x0005:  AnalyStr += "设备忙";break;
            case 0x000F:  AnalyStr += "其他错";break;
            default:AnalyStr += "无法识别的错误";
        }
        AnalyStr += "</gy></p>";
    }
    else
    {
        if(analysisType == "字符串")
        {
            AnalyStr += "<p>数据域解析：<gy>";
            AnalyStr += "字符串=";
            uint8 byte_bak = body->data[data_len];
            body->data[data_len] = '\0';
            AnalyStr += QString((char *)body->data) + "</gy></p>";
            body->data[data_len] = byte_bak ;//修改了报文原文，再改回去
        }

        else if(did_str == "0B02")
        {
            AnalyStr += "<p>数据域解析：<gy><hr>";
            QString frame645_AnalyStr;
            struct frame07645 *pframe645 = get_645_frame(body->data, body->ctrl & 0x7F);
            if(pframe645 != NULL)
            {
                analysis_07645_frame(pframe645, frame645_AnalyStr);
                AnalyStr += frame645_AnalyStr;
            }
            else
            {
                AnalyStr += "645报文不合法";
            }

        }
    }

}


/*
功能：解析7E报文
参数：7E报文首地址pframe，解析结果字符串AnalyStr
*/
void analysis_7E_frame(struct SHS_frame *pframe, QString &AnalyStr)
{
    AnalyStr="<p>7E报文解析:</p>";//textEditAnalysis
    quint32 said_num= get_le_val(pframe->said,4);
    AnalyStr += "<p>源地址:<gy>dec="+ QString::number(said_num)+",       HEX=0x"
             + QString("%1").arg(said_num,8,16,(QChar)'0').toUpper()+"</gy></p>";

    quint32 taid_num= get_le_val(pframe->taid,4);
    AnalyStr += "<p>目地址:<gy>dec="+ QString::number(taid_num)+",        HEX=0x"
             + QString("%1").arg(taid_num,8,16,(QChar)'0').toUpper()+"</gy></p>";
    AnalyStr += "<p>帧序号:<gy>"+  QString("%1(0x%2)</gy></p>").arg(pframe->seq).arg(pframe->seq,2,16,(QChar)'0');//  QString::number(pframe->seq)+ "\r\n";
    int FBD_len_left = pframe->length;
    AnalyStr += "<p>长度:<gy>"+ QString("%1(0x%2)</gy></p>").arg(FBD_len_left).arg(FBD_len_left,2,16,(QChar)'0');//QString::number(FBD_len_left)+"\r\n";

    if((said_num == 0) || (taid_num==0))//本地报文解析
    {
        struct SHS_local_frame *pframeLocal = (struct SHS_local_frame *)pframe;
        QString local_did_analy;
        QString dataAnalyType;
        get_local_cmd_analy(pframeLocal->did, local_did_analy,dataAnalyType);//本地CMD/did解析
        AnalyStr += local_did_analy;
        AnalyStr += "<p>数据域原文(hex):<gy>";
        AnalyStr += byte_num_to_hex_string_with_space((uint8 *)pframeLocal->data, (int)(pframeLocal->length-1));
        AnalyStr += "</gy></p>";
        if(dataAnalyType == "字符串")
        {
            AnalyStr += "<p>数据域解析:<gy>";
            pframeLocal->data[pframeLocal->length] = '\0';
            AnalyStr += QString((char *)pframeLocal->data) + "</gy></p>";
        }
        else
        {
            AnalyStr += "<p>数据域(dec):<gy>"+ QString::number(get_le_val(pframeLocal->data, pframeLocal->length-1)) +"</gy></p>";
        }
        return;
    }

    AnalyStr += "<p>CMD:<gy>"+ get_7E_remote_cmd_analysis(pframe->infor[0])+"</gy></p>";
    struct FBD_body *body;
    if(taid_num==0xFFFFFFFF)
    {
        AnalyStr += "<p>组地址类型:<gy>"+ QString::number((pframe->infor[1]>>6)) +"</gy></p>";
        int sid_len = pframe->infor[1] & 0x3f;
        uint8 *sid = pframe->infor+2;
        AnalyStr += "<p>组地址字节数:<gy>"+ QString::number(sid_len) +"</gy></p>";
        AnalyStr += "<p>组地址依次为:<gy>";
        for(uint8 i=0;i<sid_len;i++)
            AnalyStr += QString("%1").arg((quint8)sid[i],2,16,(QChar)'0').toUpper()+" ";
            //AnalyStr += QString::number(sid[i],16) +" ";

        AnalyStr += "</gy></p>";
        body = (struct FBD_body *)(pframe->infor + CMD_LEN +1 + sid_len);
        FBD_len_left -= CMD_LEN +1 + sid_len;
    }
    else
    {
        body = (struct FBD_body *)(pframe->infor + CMD_LEN);
        FBD_len_left -= CMD_LEN +1;
    }


    while(FBD_len_left>0)//组合body解析开始
    {
        qDebug()<<"body剩余内容:";
        print_arr(body,FBD_len_left);
        QString BodyAnalyStr="";
        get_7E_body_analysis(body, BodyAnalyStr);
        AnalyStr +=BodyAnalyStr + "<br>";

        FBD_len_left -= DID_LEN+1+(body->ctrl&0x7F);
        body = (struct FBD_body *)((uint8 *)body + DID_LEN+1+(body->ctrl&0x7F));
    }




}
